home *** CD-ROM | disk | FTP | other *** search
/ Aminet 8 / Aminet 8 (1995)(GTI - Schatztruhe)[!][Oct 1995].iso / Aminet / util / cdity / Yak210src.lha / Yak_2.10_Src / settings.c < prev    next >
C/C++ Source or Header  |  1995-08-19  |  27KB  |  924 lines

  1. #define __USE_SYSBASE
  2. #include <exec/types.h>
  3. #include <exec/memory.h>
  4. #include <dos/dos.h>
  5. #include <libraries/iffparse.h>
  6. #include <prefs/prefhdr.h>
  7. #include <proto/exec.h>
  8. #include <proto/dos.h>
  9. #include <proto/iffparse.h>
  10. #include <string.h>
  11.  
  12. #include "code.h"
  13. #include "yak.h"
  14. #include "Requesters.h"
  15. #include "handlers.h"
  16. #include "hotkey_types.h"
  17. #include "Settings.h"
  18.  
  19.  
  20. #define CATCOMP_NUMBERS
  21. #include "yak_locale_strings.h"
  22.  
  23. extern struct Library *IFFParseBase;
  24.  
  25. #if defined (PREFS) || defined (CONV)
  26. #  ifdef _DCC
  27. #    include <lists.h>
  28. #  else
  29. #    include "sas_lists.h"
  30. #  endif
  31. #  include "gui.h"
  32. #  include "Root_window.h"
  33. #  include "MouseCycling_window.h"
  34. #  include "Options_window.h"
  35. #  include "KeyDef_window.h"
  36. #  include "Blank_window.h"
  37. #  include "Misc_window.h"
  38. #  include "Hotkey_window.h"
  39.    static APTR WriteConfig(struct IFFHandle *iff, UBYTE *chunkbuf);
  40.    static APTR WriteHandlers(struct IFFHandle *iff, UBYTE *chunkbuf);
  41.    static APTR WriteHotkey(struct IFFHandle *iff, UBYTE *chunkbuf, YakHotKey *yhk);
  42. #else
  43. #  include "ClickDrive.h"
  44. #  include "BlackBorder.h"
  45. #  include "MMB_Shift.h"
  46. #  include "UnixDirs.h"
  47. #  include "FullWorkbench.h"
  48. #endif
  49.  
  50. #ifndef CONV
  51. static APTR ReadConfig(UBYTE *chunkbuf, ULONG size);
  52. static APTR ReadHandlers(UBYTE *chunkbuf, ULONG size);
  53. static APTR ReadHotkey(UBYTE *chunkbuf, ULONG size);
  54. #endif
  55.  
  56. #define ID_YKCF MAKE_ID('Y','K','C','F')
  57. #define ID_YKHD MAKE_ID('Y','K','H','D')
  58. #define ID_YKHK MAKE_ID('Y','K','H','K')
  59.  
  60. static UWORD PrefsVersionRead;
  61.  
  62. /*
  63.  * Used for compatibility
  64.  *
  65.  * +----------------+-------------+
  66.  * |YAKPREFSVERSION | Yak version |
  67.  * +----------------+-------------+
  68.  * | 0              | Yak 2.00    |
  69.  * | 1              | Yak 2.04    |
  70.  * +----------------+-------------+
  71.  */
  72.  
  73. #define YAKPREFSVERSION 1
  74.  
  75.  
  76.  
  77.  
  78. #define MAXBUFSIZE 1024
  79.  
  80.  
  81. #define DEF_AUTOPOINT_DELAY    2
  82. ULONG    autopoint_delay;           /* used for autopoint */
  83.  
  84. #define DEF_VOLUME            48
  85. ULONG    click_volume;              /* used for keyclick */
  86.  
  87. #define DEF_SCREENBLANKSECS        300
  88. ULONG    blanksecs; 
  89. ULONG    blanktimeout;
  90. ULONG    blankcount;                /* countdown to blank-time */
  91. ULONG    screenblank;               /* method used to blank screen */
  92.  
  93. #define DEF_MOUSEBLANKSECS         5
  94. ULONG    mouseblank;                /* method used to blank mouse */
  95. ULONG    mblanksecs;
  96. ULONG    mblanktimeout;
  97. ULONG    mblankcount;               /* countdown to mouse-blank-time */
  98.  
  99. static const BOOL DEF_TOGGLE[NUM_TOGGLES] = {
  100.         TRUE,         /* autopoint       */
  101.         FALSE,        /* keyactivate     */
  102.         FALSE,        /* autopop         */
  103.         FALSE,        /* rmbactivate     */
  104.         FALSE,        /* wildstar        */
  105.         TRUE,         /* scractivate     */
  106.         FALSE,        /* noclick         */
  107.         FALSE,        /* mmbactivate     */
  108.         FALSE,        /* blackborder     */
  109.         TRUE,         /* blankmouseonkey */
  110.         FALSE,        /* mmbshift        */
  111.         FALSE,        /* UnixDirs        */
  112.         FALSE,        /* SlashDir        */
  113.         FALSE         /* fullworkbench   */
  114. };
  115.  
  116.  
  117.  
  118. #ifdef PREFS
  119.  
  120. #  define TOGGLE_DESCRIPTION(DefState, Gadget, WindowID) {(BOOL)DefState, (UWORD)Gadget, (UBYTE)WindowID}
  121.  
  122. #else   /* Yak commodity only */
  123.  
  124. #  define TOGGLE_DESCRIPTION(DefState, Gadget, WindowID) {(BOOL)DefState}
  125.  
  126. #endif
  127.  
  128. ToggleData toggles[] = {
  129.         TOGGLE_DESCRIPTION( TRUE, GDX_AutoCheck,          ROOT_WINDOW),
  130.         TOGGLE_DESCRIPTION(FALSE, GDX_KeyActCheck,        ROOT_WINDOW),
  131.         TOGGLE_DESCRIPTION(FALSE, GDX_AutoPopCheck,       ROOT_WINDOW),
  132.         TOGGLE_DESCRIPTION(FALSE, GDX_RMBActCheck,        ROOT_WINDOW),
  133.         TOGGLE_DESCRIPTION(FALSE, GDX_WildStarCheck,      MISC_WINDOW),
  134.         TOGGLE_DESCRIPTION( TRUE, GDX_ScrActCheck,        ROOT_WINDOW),
  135.         TOGGLE_DESCRIPTION(FALSE, GDX_NoClickCheck,       MISC_WINDOW),
  136.         TOGGLE_DESCRIPTION(FALSE, GDX_MMBActCheck,        ROOT_WINDOW),
  137.         TOGGLE_DESCRIPTION(FALSE, GDX_BlackBorderCheck,   MISC_WINDOW),
  138.         TOGGLE_DESCRIPTION( TRUE, GDX_BlankMouseOnKey,    BLANK_WINDOW),
  139.         TOGGLE_DESCRIPTION(FALSE, GDX_MMBShiftCheck,      MISC_WINDOW),
  140.         TOGGLE_DESCRIPTION(FALSE, GDX_UnixDirsCheck,      MISC_WINDOW),
  141.         TOGGLE_DESCRIPTION(FALSE, GDX_SlashDirCheck,      MISC_WINDOW),
  142.         TOGGLE_DESCRIPTION(FALSE, GDX_FullWorkbenchCheck, MISC_WINDOW)
  143. };
  144.  
  145.  
  146. static const char *DEF_PATTERN[NUM_PATTERNS] = {
  147.          "#?",               /* autoactivation screens */
  148.          "~(Workbench)"      /* autopop windows */
  149. };
  150.  
  151. PatternData patterns[NUM_PATTERNS] = {
  152.         { "#?", NULL },                 /* autoactivation screens */
  153.         { "~(Workbench)", NULL }        /* autopop windows */
  154. };
  155.  
  156.  
  157.  
  158.  
  159. /* Chunks to stop on */
  160. #define NUMSTOPS 3
  161. LONG stopchunks[] = {
  162.         ID_PREF, ID_YKCF,
  163.         ID_PREF, ID_YKHD,
  164.         ID_PREF, ID_YKHK
  165. };
  166.  
  167. struct PrefHeader PrefHdrChunk = {
  168.       YAKPREFSVERSION, 0, 0
  169. };
  170.  
  171.  
  172.  
  173. /* parse pattern, report errors */
  174. __regargs BOOL
  175. InitPattern(char *newpatstr, PatternData *pdata)
  176. {
  177.         char *patstr = newpatstr ? newpatstr : pdata->patstr;
  178.         char *pat;
  179.         LONG len;
  180.  
  181.         if (pat = AllocVec(len = strlen(patstr)*3+10, MEMF_CLEAR))
  182.         {
  183.                 if (ParsePattern(patstr, pat, len) != -1)
  184.                 {
  185.                         if (newpatstr) strncpy(pdata->patstr, newpatstr, PATLEN);
  186.                         if (pdata->pat) FreeVec(pdata->pat); 
  187.                         pdata->pat = pat;
  188.                         return TRUE;
  189.                 }
  190.                 
  191.                 PostError("%s:\n\"%s\"", getString(Parsing_Pattern_ERR), patstr);
  192.                 FreeVec(pat);
  193.         }
  194.         else PostError(getString(Allocation_ERR));
  195.         return FALSE;
  196. }
  197.  
  198.  
  199. /* Set default settings */
  200. void
  201. SetDefaultSettings(void)
  202. {
  203.     register UWORD   i;
  204.  
  205.     /* Config */
  206.     for (i=0; i < NUM_TOGGLES; i++)
  207.         toggles[i].pos = DEF_TOGGLE[i];
  208.  
  209.     for (i=0; i< NUM_PATTERNS; i++)
  210.         strcpy(patterns[i].patstr, DEF_PATTERN[i]);
  211.  
  212.     autopoint_delay = DEF_AUTOPOINT_DELAY;
  213.     click_volume    = DEF_VOLUME;
  214.     blanksecs       = DEF_SCREENBLANKSECS;
  215.     mblanksecs      = DEF_MOUSEBLANKSECS;
  216.     mouseblank      = MB_SPRITES;
  217.     screenblank     = SB_BLACKSCREEN;
  218.  
  219.     /* Hotkeys */
  220.     DeleteYakHotKeyList();
  221.  
  222.  
  223.     /* Mouse Cycling */
  224.     CleanMouseCycling();
  225.     for (i=0; i<NUM_HANDLERS; i++)
  226.     {
  227.         CopyMem((char *)&DEF_MOUSECYCLING[i], (char *)&MouseCyclingHandlers[i], (long)sizeof(YakHandler));
  228.         MouseCyclingHandlers[i].KeyDef = DupStr(MouseCyclingHandlers[i].KeyDef);
  229.     }
  230. }
  231.  
  232. #define WORD_ALIGN(ptr) ((ULONG)(ptr + 1) & ~1)
  233.  
  234. #ifndef CONV
  235.  
  236. /* Read Preferences */
  237. void
  238. LoadSettings(char *filename)
  239. {
  240.     struct IFFHandle *iff;
  241.     APTR              error = Opening_prefs_file_ERR; /* Temporarily */
  242.     BOOL              cont = TRUE;
  243.  
  244.     /* First: set default values */
  245.     SetDefaultSettings();
  246.  
  247.     /* Allocate IFF handle */
  248.     if (iff=AllocIFF())
  249.     {
  250.         /* Open IFF File */
  251.         if (iff->iff_Stream=Open(filename, MODE_OLDFILE))
  252.         {
  253.             /* Init IFF handle */
  254.             InitIFFasDOS(iff);
  255.  
  256.             /* Open IFF handle */
  257.             if (!OpenIFF(iff, IFFF_READ))
  258.             {
  259.                 /* Set IFF chunk types */
  260.                 if (!PropChunk(iff, ID_PREF, ID_PRHD) &&
  261.                     !StopChunks(iff, stopchunks, NUMSTOPS) &&
  262.                     !StopOnExit(iff, ID_PREF, ID_FORM) )
  263.                 {
  264.                     error = Invalid_prefs_file_ERR; /* Temporarily */
  265.  
  266.                     /* Start IFF parsing */
  267.                     if (!ParseIFF(iff, IFFPARSE_STEP))
  268.                     {
  269.                         struct ContextNode *cn;
  270.  
  271.                         /* Check IFF type */
  272.                         if ( (cn=CurrentChunk(iff)) &&
  273.                             (cn->cn_ID   == ID_FORM) &&
  274.                             (cn->cn_Type == ID_PREF) )
  275.                         {
  276.                             if (!ParseIFF(iff, IFFPARSE_SCAN))
  277.                             {
  278.                                 struct StoredProperty *sp;
  279.  
  280.                                 /* Get pointer to PRHD chunk */
  281.                                 if (sp=FindProp(iff, ID_PREF, ID_PRHD))
  282.                                 {
  283.                                     struct PrefHeader *ph=(struct PrefHeader *) sp->sp_Data;
  284.                             
  285.                                     PrefsVersionRead = ph->ph_Version;
  286.  
  287.                                     error = NULL; /* No error: temporarily */
  288.  
  289.                                     /* Parse IFF chunks */
  290.                                     do
  291.                                     {
  292.                                         APTR   localerr;
  293.                                         char   localstr[5];
  294.  
  295.                                         /* Get current chunk */
  296.                                         if (cn=CurrentChunk(iff))
  297.                                         {
  298.                                             UBYTE *chunkbuf;
  299.                                             ULONG  size=cn->cn_Size;
  300.  
  301.                                             /* Allocate memory for config buffer */
  302.                                             if (chunkbuf=AllocVec(size, 0L))
  303.                                             {
  304.                                                 /* Read chunk */
  305.                                                 if (ReadChunkBytes(iff, chunkbuf, size) == size)
  306.                                                 {
  307.                                                     switch(cn->cn_ID) 
  308.                                                     {
  309.                                                       case ID_YKCF:
  310.                                                         localerr = ReadConfig(chunkbuf, size);
  311.                                                         break;
  312.                                                       case ID_YKHK:
  313.                                                         localerr = ReadHotkey(chunkbuf, size);
  314.                                                         break;      
  315.                                                       case ID_YKHD:
  316.                                                         localerr = ReadHandlers(chunkbuf, size);
  317.                                                         break;
  318.                                                     }
  319.  
  320.                                                     if (localerr)
  321.                                                     {
  322.                                                         cont = (BOOL)GetOrders(getString(Continue_Abort_ORDERS),
  323.                                                                                getString(localerr),
  324.                                                                                IDtoStr(cn->cn_ID, localstr));
  325.                                                     }
  326.                                                 }
  327.                                                 else
  328.                                                 {
  329.                                                     PostError(getString(Reading_prefs_file_ERR));
  330.                                                     cont = FALSE;
  331.                                                 }
  332.  
  333.                                                 FreeVec(chunkbuf);
  334.                                             }
  335.                                             else
  336.                                             {
  337.                                                 PostError(getString(Allocation_ERR));
  338.                                                 cont = FALSE;
  339.                                             }
  340.                                         }
  341.                                         /* Next parse step */
  342.                                     } while ((!ParseIFF(iff, IFFPARSE_SCAN)) && cont);
  343.                                 }
  344.                             }
  345.                         }
  346.                     }
  347.                 }
  348.                 CloseIFF(iff);
  349.             }
  350.             Close(iff->iff_Stream);
  351.         }
  352.         FreeIFF(iff);
  353.     }
  354.     else
  355.         PostError(getString(Allocation_ERR));
  356.  
  357.     if (error)
  358.         PostError("%s\n\"%s\"", getString(error), filename);
  359. }
  360.  
  361.  
  362.  
  363.  
  364. /* YKCF chunk format
  365.  *
  366.  *      UWORD NUM_TOGGLES
  367.  *        BOOL toggles[]
  368.  *      UWORD click_volume
  369.  *      UWORD autopoint_delay
  370.  *      UWORD blanksecs
  371.  *      UWORD mblanksecs
  372.  *      UWORD mouseblank
  373.  *      UWORD screenblank 
  374.  *      UWORD NUM_PATTERNS
  375.  *        STRING patterns[]
  376.  */
  377. static APTR
  378. ReadConfig(UBYTE *chunkbuf, ULONG size)
  379. {
  380.     UWORD *puword=(UWORD *)chunkbuf;
  381.     BOOL  *pbool;
  382.     UBYTE *pstr;
  383.     UWORD   i, n;
  384.  
  385.     if ((n=*puword) > (UWORD)NUM_TOGGLES)
  386.     {
  387.         n = (UWORD) NUM_TOGGLES;
  388.     }
  389.     pbool = puword+1;
  390.     for (i = 0; i < n; i++)
  391.         toggles[i].pos = *pbool++;
  392.     puword = pbool;
  393.         
  394.     /* Miscellaneous */
  395.         
  396.     click_volume    = *puword++;
  397.     autopoint_delay = *puword++;
  398.     blanksecs       = *puword++;
  399.     mblanksecs      = *puword++;
  400.     mouseblank      = *puword++;
  401.     
  402.     if (mblanksecs == 0)
  403.     {
  404.         mouseblank = MB_NONE;
  405.     }
  406.  
  407.     if (PrefsVersionRead > 0)
  408.     {
  409.         screenblank = *puword++;
  410.         if (blanksecs == 0)
  411.         {
  412.             screenblank = SB_NONE;
  413.         }
  414.     }
  415.  
  416.     if ((n=*puword++) <= NUM_PATTERNS)
  417.     {
  418.         pstr = (UBYTE *)puword;
  419.         for (i = 0; i < n; i++)
  420.         {
  421.             strncpy(patterns[i].patstr, pstr, PATLEN);
  422.             patterns[i].patstr[PATLEN] = '\0';
  423.             pstr += strlen(pstr)+1;
  424.         }
  425.  
  426.  
  427. #ifndef PREFS                   /* Yak */
  428.         /* set-up patterns */
  429.         for (i = 0; i < NUM_PATTERNS; i++)
  430.             InitPattern(NULL, &patterns[i]);
  431.  
  432.         if (wildstar)
  433.             WILDSTARON;
  434.         else
  435.             WILDSTAROFF;
  436.  
  437.         SetClickDrive(noclick);
  438.  
  439.         ToggleBlackBorder(blackborder);
  440.  
  441.         ToggleFullWorkbench(fullworkbench);
  442.  
  443.         ToggleUnixDirs(unixdirs);
  444.  
  445.         ToggleMMBShift(mmbshift);
  446.  
  447.         blankcount  = blanktimeout  = 10*blanksecs;
  448.         mblankcount = mblanktimeout = 10*mblanksecs;
  449. #endif
  450.  
  451.         if ((pstr-chunkbuf) == size)
  452.         { 
  453.             /* Reading Ok */
  454.             return 0L;
  455.         }
  456.  
  457.     }
  458.     return Reading_chunk_ERR;
  459. }
  460.  
  461.  
  462.  
  463. /* YKHK chunk format
  464.  *
  465.  *      UWORD  type
  466.  *      UWORD  state
  467.  *      STRING name
  468.  *      STRING keydef
  469.  *      UWORD  optsnum
  470.  *         UWORD flags
  471.  *         [ STRING argstr[] ]
  472.  *         [ LONG   argnum[] ]
  473.  *                .
  474.  *                .
  475.  *                .
  476.  *
  477.  */
  478. static APTR
  479. ReadHotkey(UBYTE *chunkbuf, ULONG size)
  480. {
  481.     register UWORD *puword=(UWORD *)chunkbuf;
  482.     register UBYTE *pstr;
  483.     void           *pvoid;
  484.     LONG           *plong;
  485.  
  486.     YakHotKey      *yhk;
  487.     UWORD           type;
  488.  
  489.     UWORD           ol, optsnum;
  490.     OptDescription *curdesc;
  491.  
  492.     if ((type=*puword++) < NUM_HOTKEY_TYPES)
  493.     {
  494.         if (yhk = NewYakHotKey(type))
  495.         {
  496.             yhk->yhk_State   = *puword++;         /* State */
  497.             pstr = (UBYTE *)puword;
  498.  
  499.             if (ModifyYHKName(yhk, pstr))         /* Name */
  500.             {
  501.                 pstr += strlen(pstr)+1;
  502.  
  503.                 /* Take care of non word aligned addresses for 68000 */
  504.                 puword = (UWORD *)WORD_ALIGN(pstr);
  505.  
  506.                 if (ModifyYHKKeyDef(yhk, pstr))   /* KeyDef */
  507.                 {
  508.                     pstr += strlen(pstr)+1;
  509.  
  510.                     /* Options */
  511.                     /* Take care of non word aligned addresses for 68000 */
  512.                     puword = (UWORD *)WORD_ALIGN(pstr);
  513.  
  514.                     optsnum = *puword++;
  515.                     pvoid   = (void *)puword;
  516.  
  517.                     for (ol=0; ol<optsnum; ol++)
  518.                     {
  519.                         UWORD as=0;   /* ArgStr number */
  520.                         UWORD an=0;   /* ArgNum number */
  521.  
  522.                         curdesc = yhktypes[yhk->yhk_Type].yhkt_OptsList[ol].Desc;
  523.  
  524.                         puword = (UWORD *)pvoid;
  525.                         yhk->yhk_Option[ol].Flags = *puword++;
  526.                         pvoid = (void *)puword;
  527.  
  528.                         while (curdesc->Type != NO_OPT)
  529.                         {
  530.                             switch(curdesc->Type)
  531.                             {
  532.                                 case STRING_OPT:
  533.                                     if (yhk->yhk_Option[ol].Flags & curdesc->LocalID)
  534.                                     {
  535.                                         pstr = (UBYTE *)pvoid;
  536.                                         yhk->yhk_Option[ol].ArgStr[as] = DupStr(pstr);
  537.                                         pstr += strlen(pstr)+1;
  538.  
  539.                                         /* Take care of non word aligned addresses for 68000 */
  540.                                         pvoid = (void *)WORD_ALIGN(pstr);
  541.                                     }
  542.                                     as++;
  543.                                     break;
  544.  
  545.                                 case INTEGER_OPT:
  546.                                     if (yhk->yhk_Option[ol].Flags & curdesc->LocalID)
  547.                                     {
  548.                                         plong = (LONG *)pvoid;
  549.                                         yhk->yhk_Option[ol].ArgNum[an] = *plong++;
  550.                                         pvoid = (void *)plong;
  551.                                     }
  552.                                     an++;
  553.                                     break;
  554.                             }
  555.  
  556.                             curdesc++;
  557.                         }
  558.                     }
  559.  
  560.                     if (((UBYTE *)pvoid-chunkbuf) == size)
  561.                         return 0L;  /* Reading Ok */
  562.  
  563.                 }
  564.  
  565.             }
  566.  
  567.             DeleteYakHotKey(yhk);
  568.         }
  569.  
  570.     }
  571.  
  572.     return Reading_chunk_ERR;
  573. }
  574.  
  575.  
  576. /* YKHD chunk format
  577.  *
  578.  *      UWORD NUM_HANDLERS
  579.  *        UWORD  handler[0].State
  580.  *        UWORD  handler[0].RequiredClicks
  581.  *        STRING handler[0].KeyDef
  582.  *        STRING handler[0].ScreenPatternStr
  583.  *               .
  584.  *               .
  585.  *               .
  586.  */
  587. static APTR
  588. ReadHandlers(UBYTE *chunkbuf, ULONG size)
  589. {
  590.     register UWORD *puword=(UWORD *)chunkbuf;
  591.     register UBYTE *pstr;
  592.  
  593.     register UWORD   i,n;
  594.  
  595.     if ((n=*puword++) <= NUM_HANDLERS)
  596.     {
  597.         for (i = 0; i < n; i++)
  598.         {
  599.             char *keydef;
  600.  
  601.             MouseCyclingHandlers[i].State = *puword++;
  602.             
  603.             MouseCyclingHandlers[i].RequiredClicks = *puword++;
  604.             
  605.             MouseCyclingHandlers[i].Options = *puword++;
  606.             
  607.             pstr = (UBYTE *)puword;
  608.  
  609.             keydef = DupStr(pstr);
  610.             if (MouseCyclingHandlers[i].KeyDef)
  611.                 FreeVec(MouseCyclingHandlers[i].KeyDef);
  612.             MouseCyclingHandlers[i].KeyDef = keydef;
  613.  
  614.             pstr += strlen(pstr)+1;
  615.             
  616.             strncpy(MouseCyclingHandlers[i].ScreenPatternData.patstr, pstr, PATLEN);
  617.  
  618.             pstr += strlen(pstr)+1;
  619.  
  620.             /* Take care of non word aligned addresses for 68000 */
  621.             puword = (UWORD *)WORD_ALIGN(pstr);
  622.  
  623.         }
  624.  
  625.         ToggleMouseCycling();
  626.  
  627.         if (((UBYTE *)puword-chunkbuf) == size)
  628.             return 0L;          /* Reading Ok */
  629.     }
  630.     return Reading_chunk_ERR;
  631. }
  632.  
  633.  
  634.  
  635. #endif
  636.  
  637. #if defined(PREFS) || defined(CONV)
  638.  
  639. /* Copy a file */
  640. #define COPYBUFSIZE 2048
  641. BOOL
  642. CopyFile(char *source, char *dest)
  643. {
  644.     BOOL  ret=FALSE;
  645.     char *copybuf;
  646.  
  647.     /* Allocate copy buffer */
  648.     if (copybuf= AllocMem(COPYBUFSIZE, 0))
  649.     {
  650.         BPTR infh;
  651.  
  652.         /* Open source file */
  653.         if (infh=Open(source, MODE_OLDFILE))
  654.         {
  655.             BPTR outfh;
  656.  
  657.             /* Open destination file */
  658.             if (outfh=Open(dest, MODE_NEWFILE))
  659.             {
  660.                 LONG n;
  661.  
  662.                 /* Copy file */
  663.                 while ((n=Read(infh, copybuf, COPYBUFSIZE)) > 0)
  664.                     if (Write(outfh, copybuf, n) != n) break;
  665.  
  666.                 /* No error? */
  667.                 if (!n) ret=TRUE;
  668.  
  669.                 Close(outfh);
  670.             }
  671.             Close(infh);
  672.         }
  673.         FreeMem(copybuf, COPYBUFSIZE);
  674.     }
  675.     else
  676.         PostError(getString(Allocation_ERR));
  677.  
  678.  
  679.     return ret;
  680. }
  681.  
  682.  
  683. /* Write Preferences */
  684. void
  685. SaveSettings(char *filename)
  686. {
  687.     UBYTE *chunkbuf;
  688.     APTR   error = Opening_prefs_file_ERR; /* Temporarily */
  689.  
  690.     /* Allocate memory for config buffer */
  691.     if (chunkbuf=AllocVec(MAXBUFSIZE, 0L))
  692.     {
  693.         struct IFFHandle *iff;
  694.  
  695.         /* Allocate IFF handle */
  696.         if (iff=AllocIFF())
  697.         {
  698.             /* Open IFF File */
  699.             if (iff->iff_Stream=Open(filename, MODE_NEWFILE))
  700.             {
  701.                 /* Init IFF handle */
  702.                 InitIFFasDOS(iff);
  703.  
  704.                 /* Open IFF handle */
  705.                 if (!OpenIFF(iff, IFFF_WRITE))
  706.                 {
  707.                     error = Writing_prefs_file_ERR; /* Temporarily */
  708.  
  709.                     /* Push FORM IFF chunk */
  710.                     if (!PushChunk(iff, ID_PREF, ID_FORM, IFFSIZE_UNKNOWN))
  711.                     {
  712.                         /* Write PRHD IFF chunk */
  713.                         if (!PushChunk(iff, 0, ID_PRHD, sizeof(struct PrefHeader)) &&
  714.                             (WriteChunkBytes(iff, 
  715.                                              (UBYTE *) &PrefHdrChunk,
  716.                                              sizeof(struct PrefHeader)) == sizeof(struct PrefHeader)) &&
  717.                             !PopChunk(iff))
  718.                         {
  719.                             YakHotKey      *yhk;
  720.                             register UWORD  type;
  721.  
  722.                             error = WriteConfig(iff, chunkbuf);
  723.  
  724.                             if (!error) error = WriteHandlers(iff, chunkbuf);
  725.  
  726.                             for (type = 0; type < NUM_HOTKEY_TYPES && !error; type++)
  727.                                 for (yhk = (YakHotKey *)GetHead(keylist(type));
  728.                                      yhk && !error;
  729.                                      yhk = (YakHotKey *)GetSucc(yhk))
  730.                                 {
  731.                                     error = WriteHotkey(iff, chunkbuf, yhk);
  732.                                 }
  733.  
  734.                         }
  735.                         if (PopChunk(iff)) /* close out the FORM */
  736.                             error = Writing_prefs_file_ERR;
  737.                     }
  738.                     CloseIFF(iff);
  739.                 }
  740.                 Close(iff->iff_Stream);
  741.             }
  742.             FreeIFF(iff);
  743.         }
  744.         FreeVec(chunkbuf);
  745.     }
  746.     else
  747.         PostError(getString(Allocation_ERR));
  748.  
  749.     if (error)
  750.         PostError("%s\n\"%s\"", getString(error), filename);
  751. }
  752.  
  753.  
  754. static APTR
  755. WriteConfig(struct IFFHandle *iff, UBYTE *chunkbuf)
  756. {
  757.     register UWORD *puword=(UWORD *)chunkbuf;
  758.     register BOOL  *pbool;
  759.     register UBYTE *pstr;
  760.  
  761.     register UWORD i;
  762.     ULONG          size=0;
  763.  
  764.     /* toggles */
  765.     *puword++ =  (UWORD) NUM_TOGGLES;
  766.     pbool     = puword;
  767.     for (i = 0; i < NUM_TOGGLES; i++)
  768.             *pbool++ = toggles[i].pos;
  769.     puword    = pbool;
  770.  
  771.     /* miscellaneous */
  772.     *puword++ = click_volume;
  773.     *puword++ = autopoint_delay;
  774.     *puword++ = blanksecs;
  775.     *puword++ = mblanksecs;
  776.     *puword++ = mouseblank;
  777.     *puword++ = screenblank;
  778.  
  779.     /* patterns */
  780.     *puword++ = NUM_PATTERNS;
  781.     pstr      = (UBYTE *)puword;
  782.     for (i = 0; i < NUM_PATTERNS; i++)
  783.     {
  784.         strcpy(pstr, patterns[i].patstr);
  785.         pstr += strlen(pstr)+1;
  786.     }
  787.  
  788.     /* Write Chunk  */
  789.     size = pstr - chunkbuf;
  790.     if ((PushChunk(iff, 0, ID_YKCF, size)) ||
  791.         (WriteChunkBytes(iff, chunkbuf, size) != size) ||
  792.         (PopChunk(iff)))
  793.        return Writing_prefs_file_ERR;
  794.  
  795.     /* All OK. */
  796.     return NULL;
  797. }
  798.  
  799. static APTR
  800. WriteHotkey(struct IFFHandle *iff, UBYTE *chunkbuf, YakHotKey *yhk)
  801. {
  802.     UWORD          *puword=(UWORD *)chunkbuf;
  803.     UBYTE          *pstr;
  804.     void           *pvoid;
  805.     LONG           *plong;
  806.     UWORD           ol, optsnum;
  807.     OptDescription *curdesc;
  808.  
  809.     ULONG    size;
  810.  
  811.     *puword++  = yhk->yhk_Type;     /* Type  */
  812.     *puword++  = yhk->yhk_State;    /* State */
  813.     pstr = (UBYTE *)puword;
  814.  
  815.     strcpy(pstr, yhk->yhk_Name);   /* Name */
  816.     pstr += strlen(pstr)+1;
  817.  
  818.     /* Take care of non word aligned addresses for 68000 */
  819.     puword = (UWORD *)WORD_ALIGN(pstr);
  820.  
  821.     strcpy(pstr, yhk->yhk_KeyDef); /* KeyDef */
  822.     pstr += strlen(pstr)+1;
  823.  
  824.     /* Options */
  825.     /* Take care of non word aligned addresses for 68000 */
  826.     puword = (UWORD *)WORD_ALIGN(pstr);
  827.  
  828.     *puword++ = optsnum  = YHK_Takes_Opt(yhk);
  829.     pvoid = (void *)puword;
  830.  
  831.     for (ol=0; ol<optsnum; ol++)
  832.     {
  833.         UWORD as=0;   /* ArgStr number */
  834.         UWORD an=0;   /* ArgNum number */
  835.  
  836.         curdesc = yhktypes[yhk->yhk_Type].yhkt_OptsList[ol].Desc;
  837.  
  838.         puword = (UWORD *)pvoid;
  839.         *puword++ = yhk->yhk_Option[ol].Flags;
  840.         pvoid = (void *)puword;
  841.  
  842.         while (curdesc->Type != NO_OPT)
  843.         {
  844.             switch(curdesc->Type)
  845.             {
  846.                 case STRING_OPT:
  847.                     if (yhk->yhk_Option[ol].Flags & curdesc->LocalID)
  848.                     {
  849.                         pstr = (UBYTE *)pvoid;
  850.                         strcpy(pstr, yhk->yhk_Option[ol].ArgStr[as]);
  851.                         pstr += strlen(pstr)+1;
  852.  
  853.                         /* Take care of non word aligned addresses for 68000 */
  854.                         pvoid = (void *)WORD_ALIGN(pstr);
  855.                     }
  856.                     as++;
  857.                     break;
  858.  
  859.                 case INTEGER_OPT:
  860.                     if (yhk->yhk_Option[ol].Flags & curdesc->LocalID)
  861.                     {
  862.                         plong = (LONG *)pvoid;
  863.                         *plong++ =yhk->yhk_Option[ol].ArgNum[an];
  864.                         pvoid = (void *)plong;
  865.                     }
  866.                     an++;
  867.                     break;
  868.             }
  869.  
  870.             curdesc++;
  871.         }
  872.     }
  873.  
  874.  
  875.     /* Write Chunk */
  876.     size = (UBYTE *)pvoid - chunkbuf;
  877.     if ((PushChunk(iff, 0, ID_YKHK, size)) ||
  878.         (WriteChunkBytes(iff, chunkbuf, size) != size) ||
  879.         (PopChunk(iff)))
  880.        return Writing_prefs_file_ERR;
  881.  
  882.     /* All OK. */
  883.     return 0L;
  884. }
  885.  
  886. static APTR
  887. WriteHandlers(struct IFFHandle *iff, UBYTE *chunkbuf)
  888. {
  889.     UWORD  *puword=(UWORD *)chunkbuf;
  890.     UBYTE  *pstr;
  891.     register UWORD i;
  892.  
  893.     ULONG    size;
  894.  
  895.     *puword++  = NUM_HANDLERS;
  896.     
  897.     for (i=0; i< NUM_HANDLERS; i++)
  898.     {
  899.         *puword++ = MouseCyclingHandlers[i].State;
  900.         *puword++ = MouseCyclingHandlers[i].RequiredClicks;
  901.         *puword++ = MouseCyclingHandlers[i].Options;
  902.         pstr = (UBYTE *)puword;
  903.         strcpy(pstr, MouseCyclingHandlers[i].KeyDef);
  904.         pstr += strlen(pstr)+1;
  905.         strcpy(pstr, MouseCyclingHandlers[i].ScreenPatternData.patstr);
  906.         pstr += strlen(pstr)+1;
  907.  
  908.         /* Take care of non word aligned addresses for 68000 */
  909.         puword = (UWORD *)WORD_ALIGN(pstr);
  910.     }
  911.  
  912.     /* Write Chunk */
  913.     size = (UBYTE *)puword - chunkbuf;
  914.     if ((PushChunk(iff, 0, ID_YKHD, size)) ||
  915.         (WriteChunkBytes(iff, chunkbuf, size) != size) ||
  916.         (PopChunk(iff)))
  917.        return Writing_prefs_file_ERR;
  918.  
  919.     /* All OK. */
  920.     return NULL;
  921. }
  922.  
  923. #endif
  924.